﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Diagnostics;


namespace VRacer
{
    /// <summary>
    /// Zawiera podstawowe funkcje pozwalajace wyznaczyc kolejny ruch tak aby byl optymalny. Musi zawierać referencje do obiektu gry.
    /// Metoda <c>Distance</c> sprawdza odległóść od danego miejsca do ściany w określonym przez wektor kierunku.
    /// </summary>
    public abstract class PathFinderPlayer : PlayerBase
    {
        protected Game _gra;

        public PathFinderPlayer(Game game)
        {
            _gra = game;
        }


        protected Point wektor;
        protected int _color;

        /// <summary>
        /// zwraca kolor do którego się dostał
        /// </summary>
        /// <param name="_point"></param>
        /// <param name="_position"></param>
        /// <param name="_speed"></param>
        /// <returns></returns>
        private int Distance(Point _point,Point _position,Point _speed)
        {
            Point nowy_position = new Point(_position.X + _speed.X + _point.X, _position.Y + _speed.Y + _point.Y);

            if (nowy_position.X < 0 || nowy_position.X > _gra.CurrentTrack.Width)
                return 0;
            if (nowy_position.Y < 0 || nowy_position.Y > _gra.CurrentTrack.Height)
                return 0;
            if (_gra.CurrentTrack.GetStartCrossPoint(_position.X, _position.Y, nowy_position.X, nowy_position.Y).X != -1)
                return 0;
            if (_gra.CurrentTrack.GetCollisionPoint(_position.X, _position.Y, nowy_position.X, nowy_position.Y).X != -1)
                return 0;
            foreach (PlayerBase pb in _gra.Players)
            {
                if (pb == this)
                    continue;

                if ((pb.Position.X == nowy_position.X) && (pb.Position.Y == nowy_position.Y))
                    return 1;//crash
            }
            if (_gra.CurrentTrack.GetFinishCrossPoint(_position.X, _position.Y, nowy_position.X, nowy_position.Y).X != -1)
                return 101 * 256 * 256;
            {
                //nowy_punkt = _gra.CurrentTrack.GetDistance(Position.X, Position.Y, Position.X + Speed.X + _point.X, Position.Y + Speed.Y + _point.Y);
                //nowy_punkt = _gra.FindPointAfterCollision(nowy_punkt, _gra.ActivePlayer);
                //nowy_color = AIDraw.GetColor((int)nowy_punkt.X, (int)nowy_punkt.Y, _gra.CurrentTrack);
                return AIDraw.GetColor((int)(nowy_position.X), (int)(nowy_position.Y), _gra.CurrentTrack);
            }
        }

        /// <summary>
        /// zwraca najlepszy możliwy wariant 
        /// </summary>
        private int NextMoveWay(Point _point, Point _position, Point _speed,int licznik)
        {
            int x,y,_color,color=0;

            color = Distance(_point, _position, _speed);
            if (color <= 1)
                return color;
            else if(color==(101 * 256 * 256))
                return color;
            
            _speed= new Point(_speed.X+_point.X,_speed.Y+_point.Y);
            _position = new Point(_position.X + _speed.X, _position.Y + _speed.Y);

            for (x = -1; x <= 1; x++)
            {
                for (y = -1; y <= 1; y++)
                {
                    if (licznik == 3) //numer jakość AI
                        _color = Distance(new Point(x, y), _position, _speed);
                    else
                        _color = NextMoveWay(new Point(x, y), _position, _speed, licznik + 1);
                    if (_color > color)
                    {
                        color = _color;
                        //wektor = new Point(x, y);
                    }
                }
            }
            return color;
        }

        /// <summary>
        /// Ustawia parametry do ruchu
        /// </summary>
        protected void FindWay()
        {
            int color, x, y;
            _color = 0;
            Point _speed = new Point(Speed.X, Speed.Y);
            Point _position = new Point(Position.X, Position.Y);

            wektor.X = 0;
            wektor.Y = 0;

            for (x = -1; x <= 1; x++)
            {
                for (y = -1; y <= 1; y++)
                {
                    if ((Speed.X == 0) && (Speed.Y == 0) && (x == 0) && (y == 0))
                        continue;
                    color = NextMoveWay(new Point(x, y),_position,_speed,1);
                    if (color > _color)
                    {
                        _color = color;
                        wektor = new Point(x, y);
                    }
                }
            }
        }
    }
}
